package com.wstuo.common.security.service;

import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.jaas.action.LoginManager;
import com.wstuo.common.ldapmq.LdapAddUserProducer;
import com.wstuo.common.security.dao.ILDAPDAO;
import com.wstuo.common.security.dao.IOrganizationDAO;
import com.wstuo.common.security.dao.IRoleDAO;
import com.wstuo.common.security.dao.IUserDAO;
import com.wstuo.common.security.dto.LDAPAuthenticationSettingDTO;
import com.wstuo.common.security.dto.LDAPDTO;
import com.wstuo.common.security.dto.LDAPQueryDTO;
import com.wstuo.common.security.dto.OrganizationDTO;
import com.wstuo.common.security.dto.UserDTO;
import com.wstuo.common.security.entity.LDAP;
import com.wstuo.common.security.entity.Organization;
import com.wstuo.common.security.entity.Role;
import com.wstuo.common.security.entity.User;
import com.wstuo.common.security.utils.AppConfigUtils;
import com.wstuo.common.util.StringUtils;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.security.auth.login.Configuration;

/**
 * LDAPService class
 * 
 */
public class LDAPService implements ILDAPService {
	private static final Logger LOGGER = Logger.getLogger(LDAPService.class);
	@Autowired
	private ILDAPDAO ldapDAO;
	@Autowired
	private IUserDAO userDAO;
	@Autowired
	private IUserInfoService userInfoService;
	@Autowired
	private IOrganizationDAO organizationDAO;
	@Autowired
	private IRoleDAO roleDAO;
	@Autowired
    private IOrganizationInnerService organizationInnerService;
    @Autowired
    private IOrganizationService organizationService;
    private static DirContext ctx;
	private static Hashtable env;
	@Autowired
	private LdapAddUserProducer ldapAddUserProducer;

	 /**
     * 保存LDAP连接信息
     * @param ldapDto
     */
    @Transactional
	public void saveLdap(LDAPDTO ldapDto) {
		LDAP ldap = new LDAP();

		LDAPDTO.dto2entity(ldapDto, ldap);
		ldapDAO.save(ldap);
	}

	/**
     * 删除LDAP连接信息
     * @param ldapIds
     */
	@Transactional
	public void deleteLdap(Long[] ldapIds) {
		ldapDAO.deleteByIds(ldapIds);
	}

	 /**
     * 修改LDAP连接信息
     * @param ldapDto
     */
	@Transactional
	public void mergeLdap(LDAPDTO ldapDto) {
		LDAP ldap = new LDAP();

		LDAPDTO.dto2entity(ldapDto, ldap);
		ldapDAO.merge(ldap);
	}

	/**
     * 分页查询LDAP配置信息列表
     * @param queryDto
     * @param sidx
     * @param sord
     * @return PageDTO
     */
	@SuppressWarnings("unchecked")
	public PageDTO findPagerLdap(LDAPQueryDTO queryDto, String sidx, String sord) {
		PageDTO p = ldapDAO.findPager(queryDto, sidx, sord);

		List<LDAP> entities = (List<LDAP>) p.getData();
		List<LDAPDTO> dtos = new ArrayList<LDAPDTO>(entities.size());

		for (LDAP entity : entities) {
			LDAPDTO dto = new LDAPDTO();

			UserDTO.entity2dto(entity, dto);
			dtos.add(dto);
		}

		p.setData(dtos);

		return p;
	}
	
	 /**
	    * getLdap GET AD USER
	    * @param page
	    * @param rows
	    * @param ldapId
	    * @return PageDTO
	    */
	@Transactional
	public PageDTO getAllLdap(int page, int rows, Long ldapId) {
		PageDTO pageDto = new PageDTO();
		List<UserDTO> userDtoList = new ArrayList<UserDTO>();
		List<UserDTO> userDtoLists = new ArrayList<UserDTO>();

		if (ldapId!=null  && ldapId != 0) {
			LDAPDTO ldapDto = getLDAPById(ldapId);
			if(ldapDto!=null){
				
			    userDtoList = this.getUserDTOListByLDAPType(ldapDto);


				int totalSize = userDtoList.size();
	
				int total = totalSize / rows;
	
				if ((totalSize % rows) != 0) {
					total = total + 1;
				}
	
				int start = ((page - 1) * rows);
	
				int end = rows * page;
	
				if (end > totalSize) {
					end = totalSize;
				}
	
				for (int i = start; i < end; i++) {
					UserDTO userDto = userDtoList.get(i);
					userDto.setUserId(Long.valueOf(i));
					userDtoLists.add(userDto);
				}
	
				pageDto.setPage(page);
				pageDto.setRows(rows);
				pageDto.setTotal(total);
				pageDto.setData(userDtoLists);
				pageDto.setTotalSize(totalSize);
			}
		}

		return pageDto;
	}

	/**
     * adUserImport
     * @param userDto
     * @return boolean
     */
	@Transactional
	public boolean adUserImport(UserDTO userDto) {
		boolean result = false;
		//判断用户是否存在
		User user = userDAO.findUniqueBy("loginName", userDto.getLoginName());
		if (user == null) {
		    result = true;
		    user = new User();
		    user.setLoginName(userDto.getLoginName());
            user.setPassword(userDto.getLoginName());
		}
		Set<Role> rolesOld = new HashSet<Role>();
        if(user.getUserState()){
        	rolesOld.addAll(user.getRoles());
        }else{
        	Role enduser=roleDAO.findUniqueBy("roleCode", "ROLE_ENDUSER");
        	rolesOld.add(enduser);
        }
		user.setCompanyNo(userDto.getCompanyNo());
        user.setEmail(userDto.getEmail());
        user.setFirstName(userDto.getFirstName());
        user.setLastName(userDto.getLastName());
        user.setFax(userDto.getFax());
        user.setMoblie(userDto.getMoblie());
        user.setPhone(userDto.getPhone());
		user.setPosition(userDto.getPosition());
        user.setOfficeAddress(userDto.getOfficeAddress());
        user.setUserState(userDto.getUserState());
        if(StringUtils.hasText(userDto.getFirstName())||StringUtils.hasText(userDto.getLastName())){
        	StringBuilder sb = new StringBuilder();
        	if(StringUtils.hasText(userDto.getFirstName())){
        		sb.append(userDto.getFirstName());
        	}
        	if(StringUtils.hasText(userDto.getLastName())){
        		sb.append(userDto.getLastName());
        	}
        	user.setFullName(sb.toString());
        }
        if (userDto.getOrgNo()!=null && userDto.getOrgNo() > 0) {
            Organization org = new Organization();
            org = organizationDAO.findById(userDto.getOrgNo());
            user.setOrgnization(org);
        }
        Set<Role> roles = new HashSet<Role>();
        roles = userInfoService.getRoleByIds(userDto.getRoleIds());
        
        //user.setRoles(roles);
		
		if (result){
			user.setRoles(roles);
			userDAO.save(user);
		}else
			userDAO.mergeByLDAP(user, roles,rolesOld);
		
		return result;
	}

	/**
     * getLDAPAll
     * @return List<LDAPDTO>
     */
	public List<LDAPDTO> getLDAPAll() {
		List<LDAP> ldapList = ldapDAO.findAll();
		List<LDAPDTO> dtos = new ArrayList<LDAPDTO>(ldapList.size());
		for (LDAP entity : ldapList) {
			LDAPDTO ldapDto = new LDAPDTO();
			LDAPDTO.entity2dto(entity, ldapDto);
			dtos.add(ldapDto);
		}
		return dtos;
	}

	/**
     * 根据ID获取LDAP信息 getLDAPById
     * @param ldapId
     * @return LDAPDTO
     */
	public LDAPDTO getLDAPById(long ldapId) {
		LDAPDTO ldapDto = new LDAPDTO();
		LDAP ldap = ldapDAO.findById(ldapId);
		LDAPDTO.entity2dto(ldap, ldapDto);
		return ldapDto;
	}

	/**
     * LDAPAuthentication 在所有LDAP下进行验证
     * @param userName
     * @param password
     * @return boolean
     */
	public boolean ldapAuthentication(String userName, String password) {
		boolean result = false;
		List<LDAPDTO> ldapDtos = this.getLDAPAll();
		result = ldapDAO.ldapAuthentication(ldapDtos, userName, password);
		return result;
	}

	/**
     * 根据LDAP ID进行连接测试，并把测试结果保存
     * @param ldapId
     * @return boolean
     */
	@Transactional
	public boolean ldapConnTest(Long ldapId) {
	    boolean flag = false;
		LDAP entity = ldapDAO.findById(ldapId);
		LDAPDTO ldapCheckDto = new LDAPDTO();
		LDAPDTO.entity2dto(entity, ldapCheckDto);
		if (ldapConfigCheck(ldapCheckDto)) {
			entity.setConnStatus("Success");
			flag = true;
		} else {
			entity.setConnStatus("Failure");
		}
		ldapDAO.merge(entity);
		return flag;
	}

	/**
     * 检查连接LDAP配置信息连接是否正确
     * @param ldapCheckDto
     * @return boolean
     */
	public boolean ldapConfigCheck(LDAPDTO ldapCheckDto) {
		boolean result = false;
		if ((ldapCheckDto.getLdapURL() != null)
				&& (ldapCheckDto.getProt() != null)
				&& (ldapCheckDto.getAdminName() != null)
				&& (ldapCheckDto.getAdminPassword() != null)
				&& (ldapCheckDto.getLdapType() != null)
				&& (ldapCheckDto.getSearchBase() != null)
				&& (ldapCheckDto.getSearchFilter() != null)) {
			try {
				if (ldapCheckDto.getLdapType().equals(
						"Microsoft AD(Active Directory)")) {
					result = microsoftLDAPCheck(ldapCheckDto);
				}

				if (ldapCheckDto.getLdapType().equals("Novell eDirectory")) {
					result = ciscoLDAPCheck(ldapCheckDto);
				}

				if (ldapCheckDto.getLdapType().equals("OpenLDAP")) {
					result = linuxLDAPCheck(ldapCheckDto);
				}

				if (ldapCheckDto.getLdapType().equals("other")) {
					result = otherLDAPCheck(ldapCheckDto);
				}
			} catch (Exception e) {
				result = false;
			}
		}
		return result;
	}
	
	/**
	 * 微软 microsoftLDAPCheck(LDAPCheckDTO ldapCheckDto)
	 */
	public boolean microsoftLDAPCheck(LDAPDTO ldapCheckDto) {
		return currentLDAPCheck(ldapCheckDto);
	}

	/**
	 * Linu linuxLDAPCheck(LDAPCheckDTO ldapCheckDto)
	 */
	public boolean linuxLDAPCheck(LDAPDTO ldapCheckDto) {
	    return currentLDAPCheck(ldapCheckDto);
	}

	/**
	 * 思科 ciscoLDAPCheck(LDAPCheckDTO ldapCheckDto)
	 */
	public boolean ciscoLDAPCheck(LDAPDTO ldapCheckDto) {
	    return currentLDAPCheck(ldapCheckDto);
	}

	/**
	 * 其他 otherLDAPCheck(LDAPCheckDTO ldapCheckDto)
	 */
	public boolean otherLDAPCheck(LDAPDTO ldapCheckDto) {
	    return currentLDAPCheck(ldapCheckDto);
	}

	/**
	 * LDAP验证配置连接测试
	 * @param dto
	 * @return boolean
	 */
	public boolean LDAPAuthenticationSettingConnTest(
			LDAPAuthenticationSettingDTO dto) {
		LDAPDTO ldapDTO = new LDAPDTO();
		ldapDTO.setLdapType(dto.getLdapType());
		ldapDTO.setLdapURL(dto.getLdapServer());
		ldapDTO.setProt(dto.getProt());
		ldapDTO.setSearchBase(dto.getSearchBase());
		ldapDTO.setAdminName(dto.getAdminName());
		ldapDTO.setAdminPassword(dto.getAdminPassword());
		ldapDTO.setSearchFilter("objectClass=*");
		return ldapConfigCheck(ldapDTO);

	}

	private void configFileWriter(LDAPAuthenticationSettingDTO dto) {
		String format = "";
		if (StringUtils.hasText(dto.getSearchBase())) {
			String[] resources = dto.getSearchBase().toString().split(",");
			if (resources != null && resources.length > 0) {
				for(String re:resources){
					String[] res =re.split("=");
					if("".equals(format) && res.length==2){
						format=res[1];
					}else if(res.length==2){
						format=format+"."+res[1];
					}
				}
			}
		}
		String JAAS_PATH = AppConfigUtils.getInstance().getCustomJAASPath();
		File krb5File = new File(JAAS_PATH + "//testkrb5.ini");
		File testFile = new File(JAAS_PATH + "//test.conf");
		File sunOneFile = new File(JAAS_PATH + "//sunOne.conf");
		FileWriter krb5FileWriter = null;
		FileWriter testFileWriter = null;
		FileWriter sunOneFileWriter = null;
		try {
			krb5FileWriter = new FileWriter(krb5File);
			testFileWriter = new FileWriter(testFile);
			sunOneFileWriter = new FileWriter(sunOneFile);
			PrintWriter krb5printer = new PrintWriter(krb5FileWriter);
			PrintWriter testprinter = new PrintWriter(testFileWriter);
			PrintWriter sunOneprinter = new PrintWriter(sunOneFileWriter);
			testprinter.printf(dto.assemblytestPapers(format));
			krb5printer.printf(dto.assemblyKrbPapers());
			sunOneprinter.printf(dto.assemblySunOnePapers());
			testprinter.close();
			krb5printer.close();
			sunOneprinter.close();
		} catch (IOException e) {
			LOGGER.error(e);
		} finally {
			try {
				if(testFileWriter!=null){
					testFileWriter.close();
				}
				if(krb5FileWriter!=null){
					krb5FileWriter.close();
				}
			} catch (IOException e) {
				LOGGER.error(e);
			}
		}
		Configuration.getConfiguration().refresh();
	}

	/**
	 * connTestkerberos验证配置连接测试
	 * @param dto
	 * @return boolean
	 */
	public boolean connTestkerberos(LDAPAuthenticationSettingDTO dto) {
		configFileWriter(dto);
		return LoginManager.login(dto.getKerberosName(), "krb5", dto.getKerberosPassword());
	}

	/**
	 * LDAP 连接测试
	 * @param dto
	 * @return boolean
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public boolean connTestldap(LDAPAuthenticationSettingDTO dto) {
		boolean result = false;
		configFileWriter(dto);
		if ("OpenLDAP".equals(dto.getLdapType())) {
			LDAPDTO ldapDTO = new LDAPDTO();
			ldapDTO.setLdapURL(dto.getLdapServer());
			ldapDTO.setProt(dto.getProt());
			ldapDTO.setAdminName(dto.getAdminName());
			ldapDTO.setAdminPassword(dto.getAdminPassword());
			ldapDTO.setLdapType(dto.getLdapType());
			ldapDTO.setSearchBase(dto.getSearchBase());
			ldapDTO.setSearchFilter("objectClass=*");
			result = ldapConfigCheck(ldapDTO);
		}else if("Sun_One_Directory_Server".equals(dto.getLdapType())){
			env = new Hashtable();
		    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
		    env.put(Context.PROVIDER_URL,dto.getLdapServer()+":"+dto.getProt());
		    env.put(Context.SECURITY_AUTHENTICATION,"simple");
		    env.put(Context.SECURITY_PRINCIPAL,dto.getAdminName());
		    env.put(Context.SECURITY_CREDENTIALS,dto.getAdminPassword());
		    try {
				ctx = new InitialDirContext(env);
				result = true;
				ctx.close();
			} catch (NamingException e) {
				LOGGER.error(e);
			}
		}else{
			result = LoginManager.login(dto.getAdminName(), "ldap", dto.getAdminPassword());
		}
		return result;
	}

	/**
     * 检测用户名在指定AD里是否存在
     * @param ldapDTO
     * @return UserDTO
     */
	@SuppressWarnings("rawtypes")
	@Transactional
	public UserDTO checkUserNameIsExist(LDAPDTO ldapDTO) {
		UserDTO userDTO = new UserDTO();
		if (ldapDTO.getLdapType().equals("Microsoft AD(Active Directory)")) {
			DirContext dctx = null;
			try {
				dctx = new InitialLdapContext(this.getLdapContext(ldapDTO), null);
				SearchControls searchCtls = new SearchControls();
				String[] attributeFilter = { "sAMAccountName", "mail",
						"givenName", "sn", "mobile", "telephoneNumber",
						"distinguishedName" };
				searchCtls.setReturningAttributes(attributeFilter);
				searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
				NamingEnumeration results = dctx.search(
						ldapDTO.getSearchBase(), ldapDTO.getSearchFilter(),
						searchCtls);

				while (results.hasMoreElements()) {
					SearchResult sr = (SearchResult) results.next();
					Attributes attrs = sr.getAttributes();
					Attribute attr = attrs.get("sAMAccountName");
					userDTO.setLoginName(attr.get().toString());
					attr = attrs.get("mail");
					if (attr != null)
						userDTO.setEmail(attr.get().toString());

					attr = attrs.get("givenName");
					if (attr != null)
						userDTO.setFirstName(attr.get().toString());

					attr = attrs.get("sn");
					if (attr != null)
						userDTO.setLastName(attr.get().toString());

					attr = attrs.get("mobile");
					if (attr != null)
						userDTO.setMoblie(attr.get().toString());

					attr = attrs.get("telephoneNumber");
					if (attr != null)
						userDTO.setPhone(attr.get().toString());

					attr = attrs.get("distinguishedName");
					if (attr != null) {
						String[] dn = attr.toString().split(",");
						String dns = "";
						if (dn.length > 0) {
							for (String str : dn) {
								if (str.indexOf("DC=") != -1
										&& str.indexOf("com") == -1) {
									if (dns.equals(""))
										dns = str.substring(3);
									else
										dns = dns + "." + str.substring(3);
								}
							}
						}
						userDTO.setDomain(dns);
						userDTO.setDistinguishedName(attr.get().toString());
					}
				}
			} catch (Exception e) {
			    LOGGER.error(e);
			} finally {
				try {
					if(dctx!=null){
						dctx.close();
					}
				} catch (NamingException e) {
					 LOGGER.error(e);
				}
			}
		}
		if (ldapDTO.getLdapType().equals("OpenLDAP")) {
			LdapContext ctx = null;
			// 异常处理
			try {
				ctx = new InitialLdapContext(this.getLdapContext(ldapDTO), null);
				LdapShaPasswordEncoder lspe = new LdapShaPasswordEncoder();
				// 搜索范围,分为"base"(本节点,SearchControls.OBJECT_SCOPE),"one"(单层,SearchControls.ONELEVEL_SCOPE),""(遍历,SearchControls.SUBTREE_SCOPE)
				SearchControls searchCtls = new SearchControls();
				searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
				NamingEnumeration answer = ctx.search(ldapDTO.getSearchBase(),
						ldapDTO.getSearchFilter(), searchCtls);
				boolean result = false;
				while (answer.hasMoreElements()) {
					SearchResult sr = (SearchResult) answer.next();
					Attributes attrs = sr.getAttributes();
					userDTO.setUserState(true);
					try {
						Attribute attr = attrs.get("userPassword");
						byte[] bytes = (byte[]) attr.get(0);
						String passwordValue = new String(bytes);
						if (passwordValue.equals(ldapDTO.getPassword()) || passwordValue.equals(lspe.encodePassword(ldapDTO.getPassword(), null))) {
							userDTO.setPassword(ldapDTO.getPassword());
							result = true;
						}
					} catch (Exception e) {
						LOGGER.error(e);
					}
					try {
						userDTO.setLoginName(attrs.get("uid").get().toString());
					} catch (Exception e) {
						LOGGER.error(e);
						userDTO.setLoginName(null);
					}
					try {
						userDTO.setEmail(attrs.get("mail").get().toString());
					} catch (Exception e) {
						LOGGER.error(e);
						userDTO.setEmail("");
					}
					try {
						userDTO.setLastName(attrs.get("sn").get().toString());
					} catch (Exception e) {
						LOGGER.error(e);
						userDTO.setLastName("");
					}
					try {
						userDTO.setMoblie(attrs.get("mobile").get().toString());
					} catch (Exception e) {
						LOGGER.error(e);
					}
					try {
						userDTO.setPhone(attrs.get("homephone").get().toString());
					} catch (Exception e) {
						LOGGER.error(e);
					}
					if (!result)
						userDTO = null;
				}
			} catch (Exception e) {
				LOGGER.error(e);
			}finally {
				try {
					if(ctx!=null){
						ctx.close();
					}
				} catch (NamingException e) {
					LOGGER.error(e);
				}
			}
		}

		return userDTO;
	}

	/**
     * LDAP用户导入
     * @param userDTO
     * @param ldapId
     * @return ldap user import result
     */
	public String ldapUserImport(UserDTO userDTO, Long ldapId) {
		int insert = 0;
		int update = 0;
		int total = 0;
		int failure = 0;
		List<UserDTO> list = new ArrayList<UserDTO>();
		LDAPDTO ldapDto = getLDAPById(ldapId);
		list = this.getUserDTOListByLDAPType(ldapDto);
		if (list != null && list.size() > 0) {
			for (UserDTO dto : list) {
				try {
					if (dto != null && dto.getLoginName() != null) {
						total++;
						/**
						 * 判断用户是否存在
						 */
						User user = userDAO.findUniqueBy("loginName",
								dto.getLoginName());
						if (user == null) {
							dto.setUserState(userDTO.getUserState());
							dto.setOrgNo(userDTO.getOrgNo());
							dto.setRoleIds(userDTO.getRoleIds());
							dto.setCompanyNo(userDTO.getCompanyNo());
							userInfoService.saveUser(dto);
							insert++;
						} else {

							user.setEmail(dto.getEmail());
							user.setFirstName(dto.getFirstName());
							user.setLastName(dto.getLastName());
							user.setFax(dto.getFax());
							user.setMoblie(dto.getMoblie());
							user.setPhone(dto.getPhone());
							user.setUserState(userDTO.getUserState());
							if ((userDTO.getOrgNo() > 0)) {
								Organization org = new Organization();
								org = organizationDAO.findById(userDTO
										.getOrgNo());
								user.setOrgnization(org);
							}
							Set<Role> roles = new HashSet<Role>();
							roles = userInfoService.getRoleByIds(userDTO
									.getRoleIds());
							//user.setRoles(roles);
							user.setCompanyNo(userDTO.getCompanyNo());
							userDAO.mergeByRoles(user, roles);
							update++;
						}
					}
				} catch (Exception e) {
					failure++;
				}

			}

		}
		return "Total:" + total + ",Insert:" + insert + ",Update:" + update
				+ ",Failure:" + failure;
	}

	/**
	 * AD域用户自动更新
	 */
	@Transactional
	public void adAutoUpdate() {
		List<LDAP> ldapList = ldapDAO.findAll();
		for (LDAP entity : ldapList) {
			LDAPDTO ldapDto = new LDAPDTO();
			LDAPDTO.entity2dto(entity, ldapDto);
			List<UserDTO> userDtoList = new ArrayList<UserDTO>();
			if ("Success".equals(ldapDto.getConnStatus())
					&& "Yes".equals(ldapDto.getIfAllowAutoImport())) {
				if ("Microsoft AD(Active Directory)".equals(
						ldapDto.getLdapType())) {
					ldapDto.setOptType("ADSync");
					userDtoList = ldapDAO.microsoftLDAP(ldapDto);
				}

				if ("Novell eDirectory".equals(ldapDto.getLdapType())) {
					userDtoList = ldapDAO.ciscoLDAP(ldapDto);
				}

				if ("OpenLDAP".equals(ldapDto.getLdapType())) {
					userDtoList = ldapDAO.linuxLDAP(ldapDto);
				}

				if ("other".equals(ldapDto.getLdapType())) {
					userDtoList = ldapDAO.otherLDAP(ldapDto);
				}
			}
			for (UserDTO userDTO : userDtoList) {
				ldapAddUserProducer.send(userDTO);
			}

		}
	}
	/**
	 * 添加LDAP域用户
	 */
	public void saveUser(UserDTO userDTO){
		User user = userDAO.findUniqueBy("loginName",
				userDTO.getLoginName());
		if (user == null) {// 新增
			if (userDTO.getUserState()) {// 如果为禁用则不做添加
				userDTO.setPassword(userDTO.getLoginName());
				userDTO.setCompanyNo(1L);// 设置默认所属客户
				Organization org=saveOrg(userDTO.getDistinguishedName());
				if(org!=null){
	 				userDTO.setOrgNo(org.getOrgNo());
	 			}else{
	 				userDTO.setOrgNo(1L);// 设置默认属性机构
	 			}
				Role role = roleDAO.findUniqueBy("roleCode",IRoleService.ROLE_ENDUSER);
				if (role != null)
					userDTO.setRoleIds(new Long[] { role.getRoleId() });
				userInfoService.saveUser(userDTO);
			}
		} else {// 更新
			Organization org=saveOrg(userDTO.getDistinguishedName());
			if(org!=null){
				user.setOrgnization(org);
 			}else{
 				user.setOrgnization(organizationDAO.findById(1l));// 设置默认属性机构
 			}
			user.setUserState(userDTO.getUserState());
			if (userDTO.getLastName() != null)
				user.setLastName(userDTO.getLastName());
			if (userDTO.getFirstName() != null)
				user.setFirstName(userDTO.getFirstName());
			user.setFullName("");
			if (userDTO.getEmail() != null)
				user.setEmail(userDTO.getEmail());
			if(StringUtils.hasText(userDTO.getOfficeAddress())){
				user.setOfficeAddress(userDTO.getOfficeAddress());
			}
			if(StringUtils.hasText(userDTO.getMoblie())){
				user.setMoblie(userDTO.getMoblie());
			}
			if(StringUtils.hasText(userDTO.getPosition())){
				user.setPosition(userDTO.getPosition());
			}
			userDAO.merge(user);
		}
	}
	/**
     * 根据域组织保存到组织架构中：
     * @param dn CN=Antony xu,OU=TDC,OU=Develop,DC=zizhou,DC=com
     */
    public Organization saveOrg(String dn){
    	Organization org =null;
    	if(StringUtils.hasText(dn)){
			String[] dnStr = dn.split(",");
			if(StringUtils.hasText(dnStr[2]) && StringUtils.hasText(dnStr[2].split("=")[1])){
				org = organizationService.findOrgByOrgNameOrparentOrgName(dnStr[1].split("=")[1],dnStr[2].split("=")[1]);
			}else{
				org = organizationService.findOrgByName(dnStr[1].split("=")[1]);
			}
			if(org==null){
		    	List<String> orgs = new ArrayList<String>();
	    		for(String str : dnStr){
	    			if(!"DC=com".equals(str)){
	    				String[] strs=str.split("=");
		    			if("CN".equals(strs[0]) || "OU".equals(strs[0]) || "DC".equals(strs[0])){
		    				orgs.add(strs[1]);
		    			}
	    			}
	    		}
	    		orgs.remove(0);
		    	if(orgs!=null && orgs.size()>0){
		    		Collections.reverse(orgs);//反序
		    		Long parentOrgNo = 1L;
		    		String parentOrgName = "";
		    		org = new Organization();
		    		for(String str : orgs){
		    			org = organizationService.findOrgByOrgNameOrparentOrgName(str,parentOrgName);
		    			if(org==null || (org!=null && org.getParentOrg()!=null 
		    					&& !parentOrgNo.equals(org.getParentOrg().getOrgNo())
		    					&& !parentOrgName.equals(org.getParentOrg().getOrgName()))){
		    				OrganizationDTO inner = new OrganizationDTO();
		    				inner.setOrgName(str);
		    				inner.setParentOrgNo(parentOrgNo);
		    				organizationInnerService.saveOrganizationInner(inner);
		    				org = organizationService.findOrgByOrgNameOrparentOrgName(str,parentOrgName);
		    				parentOrgNo = org.getOrgNo();
		    				parentOrgName = org.getOrgName();
		    			}else{
		    				parentOrgNo = org.getOrgNo();
		    				parentOrgName = org.getOrgName();
		    			}
		    		}
		    	}
			}
    	}
    	return org;
    }
    
    /**
     * 通用的 根据LDAPType 获取 UserDTOList
     * @param ldapDto
     * @return
     */
    private List<UserDTO> getUserDTOListByLDAPType(final LDAPDTO ldapDto) {
        List<UserDTO> userDtoList = new ArrayList<UserDTO>();
        if ("Microsoft AD(Active Directory)".equals(ldapDto.getLdapType()))
            userDtoList = ldapDAO.microsoftLDAP(ldapDto);

        if ("Novell eDirectory".equals(ldapDto.getLdapType()))
            userDtoList = ldapDAO.ciscoLDAP(ldapDto);

        if ("OpenLDAP".equals(ldapDto.getLdapType()))
            userDtoList = ldapDAO.linuxLDAP(ldapDto);

        if ("other".equals(ldapDto.getLdapType()))
            userDtoList = ldapDAO.otherLDAP(ldapDto);
        return userDtoList;
    }

    /**
     * 通用的LDAPCheck方法
     * @param ldapCheckDto
     * @return
     */
    private boolean currentLDAPCheck(LDAPDTO ldapCheckDto) {
        boolean result = false;
        DirContext dctx = null;
        try {
            dctx = new InitialLdapContext(this.getLdapContext(ldapCheckDto), null);
            SearchControls searchCtls = new SearchControls();
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            // NamingEnumeration results =
            // dctx.search(ldapCheckDto.getSearchBase(),ldapCheckDto.getSearchFilter(),searchCtls);
            result = true;
        } catch (Exception e) {
        	LOGGER.error(e.getMessage());
            result = false;
        } finally {
        	try {
				if(dctx!=null){
					dctx.close();
				}
			} catch (NamingException e) {
				 LOGGER.error(e);
			}
        }
        return result;
    }
    
    /**
     * 获取 LdapContext
     * @param ldapDTO
     * @return Hashtable LdapContext
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private Hashtable getLdapContext(LDAPDTO ldapDTO) {
        Hashtable hashEnv = new Hashtable();
        // LDAP访问安全级别
        hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); 
        // AD User
        hashEnv.put(Context.SECURITY_PRINCIPAL, ldapDTO.getAdminName()); 
        // AD Password
        hashEnv.put(Context.SECURITY_CREDENTIALS, ldapDTO.getAdminPassword());
        hashEnv.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        hashEnv.put(Context.PROVIDER_URL, 
                ldapDTO.getLdapURL() + ":" + ldapDTO.getProt());
        
        return hashEnv;
    }
    
}
